﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using FastColoredTextBoxNS;
using System.Text.RegularExpressions;
using HtmlAgilityPack;
using DataExtractionLanguage;

namespace WindowsWrapperEditor
{
    public partial class MainForm : Form
    {
        private Regex DelStringRegex = new Regex(@"""""|@""""|''|@"".*?""|(?<!@)(?<range>"".*?[^\\]"")|'.*?[^\\]'");
        private readonly Style BrownStyle = new TextStyle(Brushes.Brown, null, FontStyle.Italic);

        private Regex DelCommentRegex2 = new Regex(@"(/\*.*?\*/)|(/\*.*)", RegexOptions.Singleline);
        private readonly Style GreenStyle = new TextStyle(Brushes.Green, null, FontStyle.Italic);

        private Regex DelNumberRegex = new Regex(@"\b\d+[\.]?\d*([eE]\-?\d+)?[lLdDfF]?\b|\b0x[a-fA-F\d]+\b");
        private readonly Style MagentaStyle = new TextStyle(Brushes.Magenta, null, FontStyle.Regular);

        private Regex DelKeywordRegex = new Regex(@"\b(select|from|where|inner|join|outer|left|right|as|union|on)\b", RegexOptions.IgnoreCase);
        private readonly Style BlueStyle = new TextStyle(Brushes.Blue, null, FontStyle.Regular);

        private Regex DelPropertiesRegex = new Regex(@"\b(text|length|substring|getattribute)\b", RegexOptions.IgnoreCase);
        private readonly Style GrayStyle = new TextStyle(Brushes.Gray, null, FontStyle.Regular);

        private HtmlAgilityPack.HtmlDocument html = new HtmlAgilityPack.HtmlDocument();

        public MainForm()
        {
            InitializeComponent();
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            txtcodeEditor.OnTextChanged();
        }

        private void DelHighlight(Range range)
        {
            range.tb.CommentPrefix = "//";
            range.tb.LeftBracket = '(';
            range.tb.RightBracket = ')';
            range.tb.LeftBracket2 = '\x0';
            range.tb.RightBracket2 = '\x0';
            //clear style of changed range
            range.ClearStyle(BlueStyle, GrayStyle, MagentaStyle, GreenStyle, BrownStyle);

            range.SetStyle(BrownStyle, DelStringRegex);
            range.SetStyle(GreenStyle, DelCommentRegex2);
            range.SetStyle(MagentaStyle, DelNumberRegex);
            range.SetStyle(BlueStyle, DelKeywordRegex);
            range.SetStyle(GrayStyle, DelPropertiesRegex);

            range.ClearFoldingMarkers();
            range.SetFoldingMarkers("{", "}");//allow to collapse brackets block
        }

        private void txtcodeEditor_TextChanged(object sender, FastColoredTextBoxNS.TextChangedEventArgs e)
        {
            DelHighlight(e.ChangedRange);
        }

        private void btnLoad_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(txtPath.Text))
                return;

            HtmlAgilityPack.HtmlWeb web = new HtmlAgilityPack.HtmlWeb();
            html = web.Load(txtPath.Text);
            htmlTreeNode.BaseNode = html.DocumentNode;
        }

        private void htmlTreeNode_AfterSelect(object sender, TreeViewEventArgs e)
        {
            HtmlNode htmlNode = e.Node.Tag as HtmlNode;

            if (htmlNode != null)
            {
                txtXPath.Text = htmlNode.XPath.Replace('/', '.');
            }
            else
            {
                txtXPath.Text = string.Empty;
            }
        }

        private ILexical lexer = null;
        private SyntaxAnalyzer parser = null;
        private ExecutionUnit executor = null;
        private Report report = null;
        private DataTable resultTable = null;

        private void tsmiExecute_Click(object sender, EventArgs e)
        {
            report = new Report();
            lexer = new Lexical(txtcodeEditor.Text);
            parser = new SyntaxAnalyzer(lexer, report);
            executor = new ExecutionUnit(report);

            try
            {
                parser.ReadInstructions();
                resultTable = executor.Execute(parser.ParsingTree);

                tabResult.TabPages.Clear();
                tabResult.TabPages.Add(new ResultTab(resultTable));
            }
            catch (Exception ex)
            {
                if (ex.Message != "Error")
                    MessageBox.Show(ex.Message);
            }

            if (report.ErrorsReport.Count > 0)
            {
                tabResult.TabPages.Clear();
                tabResult.TabPages.Add(new ResultTab(report.ErrorsReport));
            }
        }
    }
}
